/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * GalaxiaClientUI.java
 *
 * Created on 18 Apr, 2009, 5:27:13 PM
 */
package gclient;

import java.security.NoSuchAlgorithmException;
import java.util.Hashtable;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import java.io.File;
import java.io.IOException;
import java.util.Vector;
import javax.swing.DefaultBoundedRangeModel;

/**
 *
 * @author sv
 */
public class GalaxiaClientUI extends javax.swing.JFrame {

	/** Creates new form GalaxiaClientUI */
	public GalaxiaClientUI() {
		initComponents();
		connectedToTracker = userInvited = false;
		setStatusBar("");
		dlmGroups = new javax.swing.DefaultListModel();
		listToGroup = new Hashtable<Integer, Integer>();
		lstGroups.setModel(dlmGroups);
		dmPB = new DefaultBoundedRangeModel();
		pbFileProgress.setModel(dmPB);
        fileProgressInfo = new Hashtable<Integer, Hashtable<String, Integer>>();
        tableFileInfoList = new Hashtable<Integer, Hashtable<String, FileInfo>>();

		dsp = new Dispatcher(8000, this);
	//dsp.start();
	}

	/** This method is called from within the constructor to
	 * initialize the form.
	 * WARNING: Do NOT modify this code. The content of this method is
	 * always regenerated by the Form Editor.
	 */
	@SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        lblStatusBar = new javax.swing.JLabel();
        jSplitPane1 = new javax.swing.JSplitPane();
        jScrollPane3 = new javax.swing.JScrollPane();
        lstGroups = new javax.swing.JList();
        jPanel1 = new javax.swing.JPanel();
        pbFileProgress = new javax.swing.JProgressBar();
        jScrollPane1 = new javax.swing.JScrollPane();
        lstFiles = new javax.swing.JList();
        txtFileName = new javax.swing.JTextField();
        btnDownload = new javax.swing.JButton();
        jMenuBar1 = new javax.swing.JMenuBar();
        menuFile = new javax.swing.JMenu();
        menuItemConnect = new javax.swing.JMenuItem();
        menuItemDisconnect = new javax.swing.JMenuItem();
        jSeparator2 = new javax.swing.JSeparator();
        menuItemManageKeys = new javax.swing.JMenuItem();
        jSeparator5 = new javax.swing.JSeparator();
        menuItemExit = new javax.swing.JMenuItem();
        menuGroups = new javax.swing.JMenu();
        menuItemCreateGroup = new javax.swing.JMenuItem();
        menuItemInvite = new javax.swing.JMenuItem();
        jSeparator3 = new javax.swing.JSeparator();
        menuItemLeave = new javax.swing.JMenuItem();
        menuView = new javax.swing.JMenu();
        menuItemRefresh = new javax.swing.JMenuItem();
        menuOptions = new javax.swing.JMenu();
        menuItemPreferences = new javax.swing.JMenuItem();
        jSeparator1 = new javax.swing.JSeparator();
        menuItemShareF = new javax.swing.JMenuItem();
        menuHelp = new javax.swing.JMenu();
        menuItemAbout = new javax.swing.JMenuItem();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Galaxia Client");

        lblStatusBar.setText("Status:");
        lblStatusBar.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.LOWERED));

        jSplitPane1.setDividerLocation(140);

        lstGroups.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        lstGroups.setSelectedIndex(0);
        jScrollPane3.setViewportView(lstGroups);

        jSplitPane1.setLeftComponent(jScrollPane3);

        jScrollPane1.setViewportView(lstFiles);

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(pbFileProgress, javax.swing.GroupLayout.DEFAULT_SIZE, 560, Short.MAX_VALUE)
            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 560, Short.MAX_VALUE)
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 363, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(pbFileProgress, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE))
        );

        jSplitPane1.setRightComponent(jPanel1);

        txtFileName.setToolTipText("Enter File to Download here...");

        btnDownload.setText("Download");
        btnDownload.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnDownloadActionPerformed(evt);
            }
        });

        menuFile.setText("File");

        menuItemConnect.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_N, java.awt.event.InputEvent.CTRL_MASK));
        menuItemConnect.setText("Connect");
        menuItemConnect.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                menuItemConnectActionPerformed(evt);
            }
        });
        menuFile.add(menuItemConnect);

        menuItemDisconnect.setText("Disconnect");
        menuItemDisconnect.setEnabled(false);
        menuItemDisconnect.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                menuItemDisconnectActionPerformed(evt);
            }
        });
        menuFile.add(menuItemDisconnect);
        menuFile.add(jSeparator2);

        menuItemManageKeys.setText("Manage Keys...");
        menuFile.add(menuItemManageKeys);
        menuFile.add(jSeparator5);

        menuItemExit.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F4, java.awt.event.InputEvent.CTRL_MASK));
        menuItemExit.setText("Exit");
        menuItemExit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                menuItemExitActionPerformed(evt);
            }
        });
        menuFile.add(menuItemExit);

        jMenuBar1.add(menuFile);

        menuGroups.setText("Groups");

        menuItemCreateGroup.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_G, java.awt.event.InputEvent.CTRL_MASK));
        menuItemCreateGroup.setText("Create");
        menuItemCreateGroup.setEnabled(false);
        menuItemCreateGroup.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                menuItemCreateGroupActionPerformed(evt);
            }
        });
        menuGroups.add(menuItemCreateGroup);

        menuItemInvite.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_I, java.awt.event.InputEvent.CTRL_MASK));
        menuItemInvite.setText("Invite Member(s)");
        menuItemInvite.setEnabled(false);
        menuItemInvite.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                menuItemInviteActionPerformed(evt);
            }
        });
        menuGroups.add(menuItemInvite);
        menuGroups.add(jSeparator3);

        menuItemLeave.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_X, java.awt.event.InputEvent.CTRL_MASK));
        menuItemLeave.setText("Leave");
        menuItemLeave.setEnabled(false);
        menuItemLeave.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                menuItemLeaveActionPerformed(evt);
            }
        });
        menuGroups.add(menuItemLeave);

        jMenuBar1.add(menuGroups);

        menuView.setText("View");

        menuItemRefresh.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F5, 0));
        menuItemRefresh.setText("Refresh");
        menuItemRefresh.setEnabled(false);
        menuItemRefresh.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                menuItemRefreshActionPerformed(evt);
            }
        });
        menuView.add(menuItemRefresh);

        jMenuBar1.add(menuView);

        menuOptions.setText("Options");

        menuItemPreferences.setText("Preferences");
        menuItemPreferences.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                menuItemPreferencesActionPerformed(evt);
            }
        });
        menuOptions.add(menuItemPreferences);
        menuOptions.add(jSeparator1);

        menuItemShareF.setText("Share File(s)");
        menuItemShareF.setEnabled(false);
        menuItemShareF.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                menuItemShareFActionPerformed(evt);
            }
        });
        menuOptions.add(menuItemShareF);

        jMenuBar1.add(menuOptions);

        menuHelp.setText("Help");

        menuItemAbout.setText("About...");
        menuItemAbout.setName("mnAbout"); // NOI18N
        menuItemAbout.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                menuItemAboutActionPerformed(evt);
            }
        });
        menuHelp.add(menuItemAbout);

        jMenuBar1.add(menuHelp);

        setJMenuBar(jMenuBar1);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(lblStatusBar, javax.swing.GroupLayout.DEFAULT_SIZE, 726, Short.MAX_VALUE)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jSplitPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 706, Short.MAX_VALUE)
                .addContainerGap())
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(txtFileName, javax.swing.GroupLayout.DEFAULT_SIZE, 621, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(btnDownload)
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(txtFileName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(btnDownload))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jSplitPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 391, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(lblStatusBar))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void menuItemAboutActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuItemAboutActionPerformed
	    // TODO add your handling code here:
	    if (aboutBox == null) {
		    aboutBox = new AboutDialogBox(new javax.swing.JFrame(), true);
	    }
	    aboutBox.setLocationRelativeTo(this);
	    aboutBox.setVisible(true);
}//GEN-LAST:event_menuItemAboutActionPerformed

    private void menuItemExitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuItemExitActionPerformed
	    // TODO add your handling code here:
	    setStatusBar("Qutting...");
	    try {
		    mainTracker.nodeLogout();
	    } catch (Exception e) {
		    System.err.println(e);
	    }
	    System.exit(0);
}//GEN-LAST:event_menuItemExitActionPerformed

    private void menuItemConnectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuItemConnectActionPerformed
	    // TODO add your handling code here:
	    ConnectDialogBox cdb = new ConnectDialogBox(this, true);
	    cdb.setLocationRelativeTo(this);
	    cdb.setVisible(true);
	    if (!connectedToTracker) {
		    setStatusBar("Disconnected");
	    } else {
		    setStatusBar("Connected");
		    menuItemConnect.setEnabled(false);

		    menuItemDisconnect.setEnabled(true);
		    menuItemCreateGroup.setEnabled(true);
		    menuItemRefresh.setEnabled(true);
	    }
    }//GEN-LAST:event_menuItemConnectActionPerformed

    private void menuItemRefreshActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuItemRefreshActionPerformed
	    // TODO add your handling code here:
	    setStatusBar("Refreshing View...");
	    // Add refresh code here
	    setStatusBar("");
    }//GEN-LAST:event_menuItemRefreshActionPerformed

    private void menuItemDisconnectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuItemDisconnectActionPerformed
	    // TODO add your handling code here:
	    try {
		    mainTracker.nodeLogout();
		    setStatusBar("Disconnected");
	    } catch (Exception e) {
		    System.err.println(e);
	    }
	    dlmGroups.clear();
	    menuItemDisconnect.setEnabled(false);
	    menuItemCreateGroup.setEnabled(false);
	    menuItemRefresh.setEnabled(false);
	    menuItemLeave.setEnabled(false);
	    menuItemShareF.setEnabled(false);
	    menuItemInvite.setEnabled(false);

	    menuItemConnect.setEnabled(true);
    }//GEN-LAST:event_menuItemDisconnectActionPerformed

    private void menuItemCreateGroupActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuItemCreateGroupActionPerformed
	    // TODO add your handling code here:
	    setStatusBar("Creating Group...");
	    try {
		    int newGroup = mainTracker.createGroup();
		    if (newGroup != -1) {
			    addGroup(newGroup);
		    } else {
			    setStatusBar("New group creation failed");
		    }
	    } catch (Exception e) {
		    System.err.println(e);
	    }
    }//GEN-LAST:event_menuItemCreateGroupActionPerformed

    private void menuItemLeaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuItemLeaveActionPerformed
	    // TODO add your handling code here:

	    int eltIndex = lstGroups.getSelectedIndex();
	    int eltGroup = listToGroup.get(eltIndex);

	    try {
		    mainTracker.leaveGroup(eltGroup);
	    } catch (Exception e) {
		    System.err.println(e);
	    }

	    dlmGroups.remove(eltIndex);
	    listToGroup.remove(eltIndex);

	    if (dlmGroups.isEmpty()) {
		    menuItemLeave.setEnabled(false);
		    menuItemShareF.setEnabled(false);
		    menuItemInvite.setEnabled(false);
	    }
	    setStatusBar("Left Group " + eltGroup);
    }//GEN-LAST:event_menuItemLeaveActionPerformed

    private void menuItemShareFActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuItemShareFActionPerformed
	    // TODO add your handling code here:
	    if (lstGroups.isSelectionEmpty()) {
		    javax.swing.JOptionPane.showMessageDialog(null, "Please select a group first");
		    return;
	    }
	    int selGID = listToGroup.get(lstGroups.getSelectedIndex());

	    String wd = System.getProperty("user.dir");
	    final JFileChooser fc = new JFileChooser(wd);

	    int rc = fc.showDialog(this, "Select File to Share");
	    if (rc == JFileChooser.APPROVE_OPTION) {
		    File file = fc.getSelectedFile();
		    try {
			    byte[] sha1Filename = TrackerCom.Sha1Digest(file.getName());
			    String fullPath = file.getAbsolutePath();
			    setStatusBar(file.getName());
			    boolean foo = mainTracker.addFileToGroup(selGID, new String(TrackerCom.B64Encode(sha1Filename)));
			    if (foo) {
				    setStatusBar("File Added" + fullPath);
				    FileInfo fi = new FileInfo(new String(TrackerCom.B64Encode(sha1Filename)), true, null, fullPath);
				    if (tableFileInfoList.get(selGID) == null) {
					    Hashtable<String, FileInfo> ht = new Hashtable<String, FileInfo>();
					    ht.put(new String(TrackerCom.B64Encode(sha1Filename)), fi);
                        tableFileInfoList.put(selGID, ht);
				    } else {
					    tableFileInfoList.get(selGID).put(new String(TrackerCom.B64Encode(sha1Filename)), fi);
				    }
			    } else {
				    setStatusBar("Error while adding file");
			    }
                System.out.println(getPath(new String(TrackerCom.B64Encode(sha1Filename)), selGID) );
		    } catch (Exception ex) {
			    Logger.getLogger(GalaxiaClientUI.class.getName()).log(Level.SEVERE, null, ex);
		    }
	    } else {
		    setStatusBar("No file selected");
	    }
    }//GEN-LAST:event_menuItemShareFActionPerformed

    private void menuItemInviteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuItemInviteActionPerformed
	    // TODO add your handling code here:
	    if (lstGroups.isSelectionEmpty()) {
		    javax.swing.JOptionPane.showMessageDialog(null, "Please select a group first");
		    return;
	    }
	    int selGID = listToGroup.get(lstGroups.getSelectedIndex());
	    //setSelectedGroup(selGID);

	    InviteUser iudb = new InviteUser(this, true);

	    iudb.setLocationRelativeTo(this);
	    iudb.setVisible(true);
	    if (userInvited) {
		    setStatusBar("User(s) invitations sent");
	    } else {
		    setStatusBar("No invitations sent");
	    }
    }//GEN-LAST:event_menuItemInviteActionPerformed

    private void btnDownloadActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnDownloadActionPerformed
	    // TODO add your handling code here:
	    if (txtFileName.getText().isEmpty()) {
		    JOptionPane.showMessageDialog(null, "Please enter a File Name!");
	    } else if (lstGroups.isSelectionEmpty()) {
		    JOptionPane.showMessageDialog(null, "Please select a group!");
	    } else {
		    try {
			    int gid = listToGroup.get(lstGroups.getSelectedIndex());
			    String fileName = txtFileName.getText();
			    String sha1FileName = TrackerCom.B64Encode(TrackerCom.Sha1Digest(fileName));
			    Downloader dl = new Downloader(mainTracker.getGroupUserList(gid), sha1FileName,
				    fileName, gid, mainTracker.getTrackerUserName(), this);
			    dl.start();
		    } catch (Exception ex) {
			    Logger.getLogger(GalaxiaClientUI.class.getName()).log(Level.SEVERE, null, ex);
		    }
	    }
    }//GEN-LAST:event_btnDownloadActionPerformed

    private void menuItemPreferencesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuItemPreferencesActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_menuItemPreferencesActionPerformed

	/**
	 * @param args the command line arguments
	 */
	public static void main(String args[]) {
		java.awt.EventQueue.invokeLater(new Runnable() {

			public void run() {
				try {
					javax.swing.UIManager.setLookAndFeel(javax.swing.UIManager.getSystemLookAndFeelClassName());
				} catch (Exception e) {
					System.out.println(e);
				}

				new GalaxiaClientUI().setVisible(true);
			}
		});
	}

	public void setStatusBar(String s) {
		if (s.isEmpty()) {
			lblStatusBar.setText("Status: Ready");
		} else {
			lblStatusBar.setText("Status: " + s);
		}
	}

    public void updateProgress(int gid, String sha1FileName, int amount) {
        fileProgressInfo.get(gid).put(sha1FileName, amount);
    }
    public void updateProgressBar(int amount) {
        dmPB.setValue(amount);
    }

	public void setTrackerConn(boolean b) {
		connectedToTracker = b;
	}

	public void setUserInvited(boolean userInvited) {
		this.userInvited = userInvited;
	}

	public int getSelectedGroup() {
		return listToGroup.get(lstGroups.getSelectedIndex());
	}

	/*public void setSelectedGroup(int selectedGroup) {
	this.selectedGroup = selectedGroup;	}*/
	public boolean isFileAvailable(int gid, String sha1FN) {
		if (tableFileInfoList.get(gid).get(sha1FN) == null) {
			return false;
		} else {
			return true;
		}
	}

	public Vector<Integer> availableChunks(String sha1FN, int gid) {
		if (!isFileAvailable(gid, sha1FN)) {
			return null;
		}
		if (isFullyAvailable(sha1FN, gid)) {
			return null;
		}
		return tableFileInfoList.get(gid).get(sha1FN).getAvailableChunks();
	}

	public String getPath(String sha1FN, int gid) {
		if (!isFileAvailable(gid, sha1FN)) {
			return null;
		} else {
			return tableFileInfoList.get(gid).get(sha1FN).getFilePath();
		}
	}

	public boolean isFullyAvailable(String sha1FN, int gid) {
		if (!isFileAvailable(gid, sha1FN)) {
			return false;
		} else {
			return tableFileInfoList.get(gid).get(sha1FN).isFullyAvailable();
		}
	}

	public void addChunkAvailable(int gid, String sha1FN, int chunkNumber) {
		tableFileInfoList.get(gid).get(sha1FN).addChunk(chunkNumber);
	}

	public void setFileFullyAvailable(int gid, String sha1FN, String fPath) {
		if( tableFileInfoList.get(gid) == null ) {
			tableFileInfoList.put(gid, new Hashtable<String, FileInfo>());
			FileInfo value = new FileInfo(sha1FN, true, null, fPath);
			tableFileInfoList.get(gid).put(sha1FN, value);
		}
		if ( tableFileInfoList.get(gid).get(sha1FN) == null ) {
			FileInfo value = new FileInfo(sha1FN, true, null, fPath);
			tableFileInfoList.get(gid).put(sha1FN, value);
		} else {
			tableFileInfoList.get(gid).get(sha1FN).setFullyAvailable(true);
		}
	}

	public boolean confirmInvitation(String invUName, int gid) {
		int foo = JOptionPane.NO_OPTION;

		String msg = "User " + invUName + " has invited you to join Group [ " + gid + " ]. Would you like to accept?";
		foo = JOptionPane.showConfirmDialog(null, msg);
		return (foo == JOptionPane.YES_OPTION);
	}

	public void showInvitationAccepted(String uName, int gid) {
		String msg = uName + " has accepted your invitation to join Group [ " + gid + " ]";
		JOptionPane.showMessageDialog(null, msg);
	}

	public void showInvitationRejected(String uName, int gid) {
		String msg = uName + " has rejected your invitation to join Group [ " + gid + " ]";
		JOptionPane.showMessageDialog(null, msg);
	}

	public void showFileNotFound(String fileName) {
		JOptionPane.showMessageDialog(null, fileName + " not found!");
	}

	public void showDownloadComplete(String fileName) {
		JOptionPane.showMessageDialog(null, fileName + " download complete!");
	}

	public void addGroup(int gid) {
		int eltCount = dlmGroups.size();
		listToGroup.put(eltCount, gid);
		dlmGroups.addElement("Group [" + gid + "]");
		if (eltCount == 0) {
			lstGroups.setSelectedIndex(0);
		}
		setStatusBar("Group " + gid + " added");
		if (!menuItemLeave.isEnabled()) {
			menuItemLeave.setEnabled(true);
			menuItemShareF.setEnabled(true);
			menuItemInvite.setEnabled(true);
		}
	}

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnDownload;
    private javax.swing.JMenuBar jMenuBar1;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JSeparator jSeparator1;
    private javax.swing.JSeparator jSeparator2;
    private javax.swing.JSeparator jSeparator3;
    private javax.swing.JSeparator jSeparator5;
    private javax.swing.JSplitPane jSplitPane1;
    private javax.swing.JLabel lblStatusBar;
    private javax.swing.JList lstFiles;
    private javax.swing.JList lstGroups;
    private javax.swing.JMenu menuFile;
    private javax.swing.JMenu menuGroups;
    private javax.swing.JMenu menuHelp;
    private javax.swing.JMenuItem menuItemAbout;
    private javax.swing.JMenuItem menuItemConnect;
    private javax.swing.JMenuItem menuItemCreateGroup;
    private javax.swing.JMenuItem menuItemDisconnect;
    private javax.swing.JMenuItem menuItemExit;
    private javax.swing.JMenuItem menuItemInvite;
    private javax.swing.JMenuItem menuItemLeave;
    private javax.swing.JMenuItem menuItemManageKeys;
    private javax.swing.JMenuItem menuItemPreferences;
    private javax.swing.JMenuItem menuItemRefresh;
    private javax.swing.JMenuItem menuItemShareF;
    private javax.swing.JMenu menuOptions;
    private javax.swing.JMenu menuView;
    private javax.swing.JProgressBar pbFileProgress;
    private javax.swing.JTextField txtFileName;
    // End of variables declaration//GEN-END:variables
	public TrackerCom mainTracker;
	private javax.swing.JDialog aboutBox;
	private boolean connectedToTracker,  userInvited;
	protected javax.swing.DefaultListModel dlmGroups;
	protected DefaultBoundedRangeModel dmPB;
	protected Hashtable<Integer, Integer> listToGroup;
	protected Hashtable<Integer, Hashtable<String, FileInfo>> tableFileInfoList;
    protected Hashtable<Integer, Hashtable<String, Integer>> fileProgressInfo;
	protected Dispatcher dsp;
}
